#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

const int maxn = 1500;
int linked[maxn];
bool visited[maxn];

vector<vector<int> > graph;
int n, m, nx, ny;

void init_bipartite()
{
	cin >> n >> m;
	char map[n][m];
	int da[n][m];
	fill(da[0], da[0] + n*m, -1);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++) cin >> map[i][j];

	int num = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m;) {
			while (map[i][j] == '#' && j < m) j++;
			if (j >= m) continue;
			for (; map[i][j] != '#' && j < m; j++) da[i][j] = num;
			num++;
		}
	}
	nx = num;
	graph.clear();
	graph.resize(nx + 1);

	num = 0;
	for (int j = 0; j < m; j++) {
		for (int i = 0; i < n;) {
			while (map[i][j] == '#' && i < n) i++;
			if (i >= n) continue;
			for (; map[i][j] != '#' && i < n; i++) {
				if (map[i][j] == 'o')
					graph[da[i][j]].push_back(num);
			}
			num++;
		}
	}
	ny = num;
}

typedef vector<int>::iterator iter_edge;
bool hungarian_dfs(int u)
{
	for (iter_edge it = graph[u].begin(); it != graph[u].end(); it++) {
		int v = *it;
		if (!visited[v]) {
			visited[v] = true;
			if (linked[v] == -1 || hungarian_dfs(linked[v])) {
				linked[v] = u;
				return true;
			}
		}
	}
	return false;
}

int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin >> t;
	for (int ti = 1; ti <= t; ti++) {
		cout << "Case :" << ti << endl;
		init_bipartite();

		fill(linked, linked + ny, -1);
		int count = 0;
		for (int i = 0; i < nx; i++) {
			fill(visited, visited + ny, false);
			if (hungarian_dfs(i)) count++;
		}
		cout << count << endl;
	}
}

